package com.wxy.favorites.service;

import com.wxy.favorites.constant.PublicConstants;
import com.wxy.favorites.converter.MomentConverter;
import com.wxy.favorites.core.ApiResponse;
import com.wxy.favorites.core.NoRollbackException;
import com.wxy.favorites.dao.MomentRepository;
import com.wxy.favorites.dto.MomentSaveDto;
import com.wxy.favorites.dto.MomentUpdateDto;
import com.wxy.favorites.entity.Moment;
import com.wxy.favorites.core.PageInfo;
import com.wxy.favorites.security.ContextUtils;
import com.wxy.favorites.security.SecurityUser;
import com.wxy.favorites.util.AssertUtils;
import com.wxy.favorites.util.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @Author wangxiaoyuan
 * @Date 2020/4/24 11:50
 * @Description
 **/
@Slf4j
@Service
@Transactional(noRollbackFor = NoRollbackException.class)
public class MomentService {

    @Autowired
    private MomentRepository momentRepository;

    public Moment save(Moment moment) {
        return momentRepository.save(moment);
    }

    public Moment findById(Integer id) {
        return momentRepository.findById(id).orElse(null);
    }

    public Boolean deleteById(Integer id) {
        momentRepository.deleteById(id);
        return true;
    }

    public Moment findTopMoment(Integer userId) {
        return momentRepository.findTopMoment(userId);
    }

    public PageInfo<Moment> findPageByUserIdAndTextLike(Integer userId, String text, Integer pageNum, Integer pageSize) {
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "createTime"));
        orders.add(new Sort.Order(Sort.Direction.DESC, "id"));
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by(orders));
        Page<Moment> page = momentRepository.findPageByUserIdAndTextLike(userId, "%" + SqlUtils.trimAndEscape(text) + "%", pageable);
        return new PageInfo<>(page.getContent(), page.getTotalPages(), page.getTotalElements());
    }

    public List<Moment> findByUserId(Integer userId) {
        return momentRepository.findByUserId(userId);
    }

    public List<Moment> findMoment(Integer userId, String text) {
        text = SqlUtils.trimAndEscape(text);
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "createTime"));
        orders.add(new Sort.Order(Sort.Direction.DESC, "id"));
        return momentRepository.findByUserIdAndTextLike(userId, "%" + text + "%", Sort.by(orders));
    }

    public int countByUserId(Integer userId) {
        return momentRepository.countByUserId(userId);
    }

    public Moment update(Moment moment) {
        return momentRepository.save(moment);
    }

    public Integer saveMoment(MomentSaveDto dto) {
        Moment moment = MomentConverter.INSTANCE.toMoment(dto);
        SecurityUser user = ContextUtils.getCurrentUser();
        moment.setUserId(user.getId());
        moment.setCreateTime(new Date());
        momentRepository.save(moment);
        return moment.getId();
    }

    public Boolean updateMoment(MomentUpdateDto dto) {
        Moment moment1 = momentRepository.findById(dto.getId()).orElse(null);
        AssertUtils.notNull(moment1, "瞬间不存在");
        moment1.setContent(dto.getContent());
        moment1.setText(dto.getText());
        momentRepository.save(moment1);
        return true;
    }

    public Boolean setTop(Integer id) {
        Moment moment1 = momentRepository.findById(id).orElse(null);
        AssertUtils.notNull(moment1, "瞬间不存在");
        // 取消已有置顶
        SecurityUser user = ContextUtils.getCurrentUser();
        Optional.ofNullable(findTopMoment(user.getId())).ifPresent(m -> {
            m.setIsTop(0);
            momentRepository.save(m);
        });
        // 设置新置顶
        moment1.setIsTop(PublicConstants.MOMENT_TOP_CODE);
        momentRepository.save(moment1);
        return true;
    }

    public Boolean cancelTop(Integer id) {
        Moment moment = momentRepository.findById(id).orElse(null);
        AssertUtils.notNull(moment, "瞬间不存在");
        moment.setIsTop(0);
        momentRepository.save(moment);
        return true;
    }
}

